<?php
/**
 * Created by PhpStorm.
 * User: admin
 * Date: 2019/6/20
 * Time: 19:55
 */

namespace iBrand\Shop\Server\Controllers\V2;


use iBrand\Component\Goods\Models\Goods;
use iBrand\Component\Goods\Models\GoodsProduct;
use iBrand\Component\Goods\Repositories\GoodsProductRepository;
use iBrand\Component\Purchase\Models\Transfer;
use iBrand\Component\Purchase\Repositories\TransferItemRepository;
use iBrand\Component\Purchase\Repositories\TransferRepository;
use iBrand\Shop\Core\Repositories\O2oGoodsProductsRepository;
use iBrand\Shop\Core\Repositories\O2oGoodsRepository;
use iBrand\Shop\Core\Service\WarehouseService;
use iBrand\Shop\Server\Resources\TransferItemResource;
use iBrand\Shop\Server\Resources\TransferResource;
use Illuminate\Support\Facades\DB;

class TransferController extends \iBrand\Common\Controllers\Controller
{

    protected $transferRepository;
    protected $goodsProductRepository;
    protected $warehouseService;
    protected $o2oGoodsRepository;
    protected $o2oGoodsProductsRepository;
    protected $transferItemRepository;

    public function __construct(TransferRepository $transferRepository,
                                GoodsProductRepository $goodsProductRepository,
                                WarehouseService $warehouseService,
                                O2oGoodsRepository $o2oGoodsRepository,
                                O2oGoodsProductsRepository $o2oGoodsProductsRepository,
                                TransferItemRepository $transferItemRepository)
    {
        $this->transferRepository = $transferRepository;
        $this->goodsProductRepository = $goodsProductRepository;
        $this->warehouseService = $warehouseService;
        $this->o2oGoodsRepository = $o2oGoodsRepository;
        $this->o2oGoodsProductsRepository = $o2oGoodsProductsRepository;
        $this->transferItemRepository = $transferItemRepository;
    }

    public function saveTransfer()
    {
        $clerk = auth('clerk')->user();
        $remark = request('remark');
        $type = request('type');  //调出transfer_out ; 调入transfer_in

        $goods = request('goods');
        $goodsCollect = collect($goods);

        try {
            DB::beginTransaction();

            if ($type == 'transfer_out') { //从本门店调出
                $out_shop_id = $clerk->shop_id;
                $inShopID = request('in_shop_id');
                $status = 0;

                if (!$inShopID) {
                    $status = 1;
                }
            } else {
                $out_shop_id = 0;
                $inShopID = $clerk->shop_id;
                $status = 1;
            }

            $transferData = [
                'out_shop_id' => $out_shop_id,
                'in_shop_id' => $inShopID,
                'code' => 'AL' . date('YmdHis') . mt_rand(10000000, 99999999),
                'clerk_id' => $clerk ? $clerk->id : 0,
                'total' => $goodsCollect->sum('quantity'),
                'remark' => $remark,
                'type' => $type,
                'status' => $status
            ];
            $transfer = $this->transferRepository->create($transferData);

            $total_amount = 0;
            foreach ($goods as $good) {
                $factory_price = isset($good['price']) ? $good['price'] : 0;
                if ($good['currentSku']) {
                    $product = $this->goodsProductRepository->getProductBySku($good['currentSku']);
                    $item_id = $product->id;
                    $item_type = GoodsProduct::class;

                    if (!$factory_price) {
                        $factory_price = $product->goods->factory_price;
                        $good['price'] = $factory_price;
                    }
                } else {
                    $item_id = $good['goods_id'];
                    $item_type = Goods::class;
                }

                if (!$factory_price) {
                    return $this->failed('进货价不存在');
                }

                if ($type == 'transfer_out' AND $good['beforeNumber'] < $good['quantity']) {
                    return $this->failed('调出数量错误');
                }

                $total_amount += $good['price'] * $good['quantity'];

                $this->warehouseService->addTransferItem($transfer->id, $good, $item_id, $item_type);

                $this->warehouseService->addTransferStockRecord($transfer, $good, $item_id, $item_type);

                if ($transfer->in_shop_id AND !$transfer->out_shop_id) {
                    $inO2oGoods = $this->o2oGoodsRepository->findWhere(['status' => 1, 'goods_id' => $good['goods_id'], 'shop_id' => $transfer->in_shop_id])->first();
                    if (!$inO2oGoods) {
                        $inO2oGoods = $this->o2oGoodsRepository->create([
                            'goods_id' => $good['goods_id'],
                            'shop_id' => $transfer->in_shop_id,
                            'price' => $factory_price,
                        ]);
                    }
                    $this->warehouseService->addO2oGoodsProduct($inShopID, $inO2oGoods->id, $good['goods_id'], $good['quantity'], 'Transfer', Transfer::TYPE_IN, $item_id);
                    $inO2oGoods->restoreStock($good['quantity']);

                    $this->warehouseService->handleStock($transfer, $good, $transfer->in_shop_id, $good['quantity'], $item_id, $item_type);
                }


                if ($transfer->out_shop_id) {
                    $outO2oGoods = $this->o2oGoodsRepository->findWhere(['status' => 1, 'goods_id' => $good['goods_id'], 'shop_id' => $transfer->out_shop_id])->first();
                    $outO2oGoodsId = $outO2oGoods->id;
                    $this->deleteOutO2oGoodsProduct($outO2oGoodsId, $good, $item_id, $transfer->out_shop_id);

                    $outO2oGoods->reduceStock($good['quantity']);
                }
            }

            $transfer->total_amount = $total_amount;
            $transfer->save();


            DB::commit();

            return $this->success();
        } catch (\Exception $exception) {
            \Log::info($exception->getMessage());
            \Log::info($exception->getTraceAsString());
            return $this->failed('操作失败');
        }
    }

    private function deleteOutO2oGoodsProduct($o2oGoodsId, $good, $product_id, $out_shop_id)
    {
        $o2oGoodsProduct = $this->o2oGoodsProductsRepository->findWhere(['shop_id' => $out_shop_id, 'o2o_goods_id' => $o2oGoodsId, 'goods_id' => $good['goods_id'], 'product_id' => $product_id])->first();
        $o2oGoodsProduct->store_nums = $o2oGoodsProduct->store_nums - $good['quantity'];
        $o2oGoodsProduct->save();
    }

    /*
     * 获取调拨记录
     * */
    public function getTransferList()
    {
        $clerk = auth('clerk')->user();
        $condition = $this->searchCondition();

        $list = $this->transferRepository->getTransferPaginate($clerk->shop_id, $condition[0], $condition[1], 20);

        return $this->paginator($list, TransferResource::class);
    }

    private function searchCondition()
    {
        $where = [];
        $time = [];

        if (request('code')) {
            $where['code'] = ['like', '%' . request('code') . '%'];
        }

        if (!empty(request('etime')) && !empty(request('stime'))) {
            $where['created_at'] = ['<=', request('etime')];
            $time['created_at'] = ['>=', request('stime')];
        }

        if (!empty(request('etime'))) {
            $time['created_at'] = ['<=', request('etime')];
        }

        if (!empty(request('stime'))) {
            $time['created_at'] = ['>=', request('stime')];
        }

        return [$where, $time];
    }

    /**
     * 获取调拨记录明细
     * @return mixed
     */
    public function getTransferItem()
    {
        $id = request('id');
        $limit = request('limit') ? request('limit') : 20;
        $list = $this->transferItemRepository->scopeQuery(function ($query) use ($id) {
            return $query->where('transfer_id', $id);
        })->paginate($limit);

        return $this->paginator($list, TransferItemResource::class);
    }

    /**
     * 确认收货
     */
    public function confirm()
    {
        $transfer = $this->transferRepository->find(request('id'));
        if ($transfer->in_shop_id) {
            foreach ($transfer->items as $item) {
                $inO2oGoods = $this->o2oGoodsRepository->findWhere(['status' => 1, 'goods_id' => $item->goods_id, 'shop_id' => $transfer->in_shop_id])->first();
                $product = $item->product;
                if (!$inO2oGoods) {
                    $inO2oGoods = $this->o2oGoodsRepository->create([
                        'goods_id' => $item->goods_id,
                        'shop_id' => $transfer->in_shop_id,
                        'price' => $product->goods->factory_price,
                    ]);
                }
                $this->warehouseService->addO2oGoodsProduct($transfer->in_shop_id, $inO2oGoods->id, $item->goods_id, $item->count, 'Transfer', Transfer::TYPE_IN, $product->id);
                $inO2oGoods->restoreStock($item->count);

                $good = $item->meta;
                $good['currentSku'] = $item->meta['sku'];

                $item_id = $item->item_id;
                $item_type = $item->item_type;
                $this->warehouseService->handleStock($transfer, $good, $transfer->in_shop_id, $item->count, $item_id, $item_type);
            }

            $transfer->status = 1;
            $transfer->save();

        }

        return $this->success();
    }

}